Computer systems and related technology affect many aspects of society. Indeed, the computer system's ability to process information has transformed the way we live and work. Computer systems now commonly perform a host of tasks (e.g., word processing, scheduling, and database management) that prior to the advent of the computer system were performed manually. More recently, computer systems have been coupled to one another and to other electronic devices to form both wired and wireless computer networks over which the computer systems and other electronic devices can transfer electronic data. As a result, many tasks performed at a computer system (e.g., voice communication, accessing electronic mail, transaction processing, Web browsing, and printing documents) include the exchange of electronic messages between a number of computer systems and/or other electronic devices via wired and/or wireless computer networks.
A feature of most, if not all, transaction processing systems is what is commonly referred to as a two-phase commit protocol. A two-phase commit protocol enables a number of different components (as part of the same transaction) to do some processing and agree on an outcome. The two-phase commit protocol also enables different components to be returned to their pre-transaction state when some error conditions occur. Since, a single transaction can update many different components (e.g., databases), the two-phase commit protocol strategy is designed to ensure that either all the components are updated or none of them, so that the components remain consistent. That is, the two-phase commit protocol attempts to maintain the atomicity of transactions by executing transactions in two phases, a prepare phase and a commit phase.
In a prepare phase, a transaction manager identifies what resources are necessary to a transaction and what components should be contacted to access the necessary resources. The transaction manager then attempts to contact the components by sending a prepare message requesting that the components commit to performing an operation on the necessary resource according to the transaction.
Components that are in a state (or that subsequently transition into a state) capable of performing operations requested in a prepare message, indicate this capability back to the transaction manager by sending a prepare complete message to the transaction coordinator. A prepare complete message further indicates that a component will remain in a state capable of applying the requested operations even if the component subsequently fails. However, if any component does not respond or responds that it is not capable of performing operations according to the transaction, the transaction manager may abort the transaction.
In a commit phase (after a prepare phase is successful), the transaction manager sends a commit message to all components participating in the transaction (i.e., any component from which the transaction coordinator received a prepare complete message). Reception of a commit message causes a component to perform any operations that were indicated as being prepared in a previously corresponding prepare complete message. After a component successfully performs the indicated operations, the component sends a commit complete message back to the transaction manager.
Use of a transaction manager results in sole ownership of a transaction environment and a single decision maker for decisions related to the transaction. Accordingly, there is a single concept of a transaction, a single concept of an environment, and a single concept of a thread of control. This singular control over a transaction promotes a consistent transaction meaning for the lifetime of the transaction.
Unfortunately, using of a single transaction manager is not always the most efficient way to process transactions. For example, distributing the processing of different portions of a transaction across different federated transaction managers can result in performance gains relative to processing a transaction at single transaction manager. Further, in some environments, use of different transaction managers may be required for various different portions of a transaction. For example, file systems operations may be required to be processed by a specialized file system transaction manager. Thus, when a transaction includes file system operations along with other types of operations, the file system operations are processed at the specialized file system transaction manager and the other operations are processed at a different general purpose transaction manager.
Thus, in these environments a global transaction can involve a federation of local transaction managers. However, due to the varied transaction manager configurations, different transaction managers in a federation can have different understandings of a transaction. For example, different transaction managers can have different understandings of how transactions are delimited (e.g., where a transaction starts and ends). Without some intervening processing, these different understandings of a transaction can lead to data inconsistencies or even prevent a transaction from occurring.
Some mechanisms that attempt to prevent or to compensate for different understandings of a transaction include a parent transaction manager informing subordinate resource managers that a transaction has begun, and is active or inactive. However, the parent transaction manager has no way to know beforehand what other transaction managers in a federation might process part of the transaction. Thus, to insure a common understanding across all transaction managers, the parent transaction manager informs all corresponding resource managers, even those resource managers that are not being used by a calling application. Accordingly, this mechanism is somewhat inefficient since resource managers that will have nothing to do with the transaction are informed of the transaction.
Other mechanisms that attempt to prevent or to compensate for different understandings of a transaction include resource managers enlisting with a parent transaction manager when provided with a transaction. These other mechanisms are more efficient since resource managers enlist with the parent transaction manager in response to being provided with a transaction. However, these other mechanisms do not allow the parent transaction manager to register with resources managers. Thus, when a resource manager receives a transaction, the relationship to the parent transaction manager must already be known.
Another potential solution is to develop applications that are capable of communicating directly with a variety of differently configured transaction managers. However, this potential solution requires a developer to code routines for communicating with various different transaction managers that may never be utilized. Further, if other differently configured transaction managers are created after application development is complete, the application may have no way to communicate with these other differently configured transaction managers. Thus, the developer may have to code additional routines for communicating with these other differently configured transaction managers. This type of repetitive and potentially unnecessary coding is timing consuming and burdensome to developers.